package com.tyqx.hashchainbiz.controller.jzt;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.tyqx.hashchainbean.module.HashChainStatistics;
import com.tyqx.hashchainbean.module.JZTAttachmentBusiness;
import com.tyqx.hashchainbean.module.TrackUser;
import com.tyqx.hashchainbean.vo.*;
import com.tyqx.hashchainbiz.controller.config.JwtTokenUtil;
import com.tyqx.hashchainbiz.controller.mongodb.MongoDBGridFSUtil;
import com.tyqx.hashchainbiz.service.HashChainStatisticsService;
import com.tyqx.hashchainbiz.service.JZTAttachmentBusinessService;
import com.tyqx.hashchainbiz.service.MysqlDataBaseAndMongDbConfigService;
import com.tyqx.hashchainbiz.service.TrackUserService;
import com.tyqx.hashchainutil.common.mongodb.ImagePathHashValueUtil;
import com.tyqx.hashchainutil.common.mongodb.MongoDBUtil;
import hashchainutil.common.Dto;
import hashchainutil.common.DtoUtil;
import hashchainutil.common.EmptyUtils;
import io.swagger.annotations.Api;
import org.apache.commons.io.IOUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Api(description = "JZT追溯信息")
@RestController
@RequestMapping("/JZTApi/logistics")
@CrossOrigin
public class JZTAttachmentBusinessController {


    @Resource
    private JZTAttachmentBusinessService jztAttachmentBusinessService;

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private MongoDBUtil mongoDBUtil;

    @Resource
    private MongoDatabase mongoDatabase;

    @Resource
    private TrackUserService trackUserService;

    @Resource
    private HashChainStatisticsService hashChainStatisticsService;

    @Resource
    private MysqlDataBaseAndMongDbConfigService mysqlDataBaseAndMongDbConfigService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @RequestMapping(value = "/addJZTBatchAttachmentBusiness", method = RequestMethod.POST)
    @ResponseBody
    public Dto addJZTAttachmentBusiness(HttpServletRequest request) throws Exception {
        if (true){
            return null;
        }
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        InputStream multiStream = multipartRequest.getInputStream();

        List<MultipartFile> files = multipartRequest.getFiles("files");
        String businessOrderNumber = request.getParameter("businessOrderNumber");
        String userName = request.getParameter("userName");
        if (files.size() < 1) {
            return DtoUtil.returnFail("文件不能为空", "100001");
        }
        if (EmptyUtils.isEmpty(userName)) {
            return DtoUtil.returnFail("用户名不能为空", "100002");
        }
        if (EmptyUtils.isEmpty(businessOrderNumber)) {
            return DtoUtil.returnFail("业务单号不能为空", "100003");
        }
        TrackUser trackUser=trackUserService.getUserByCode(userName);
        if(EmptyUtils.isEmpty(trackUser)){
            return DtoUtil.returnFail("附件信息携带的用户名找不到", "100004");
        }
        String msg = "";
        try {
            Integer flag = 0;
            List<JZTAttachmentBusiness> jztAttachmentBusinessList = new ArrayList<>();
            for (int i = 0; i < files.size(); i++) {
                MultipartFile file = files.get(i);
                String contentType = file.getContentType();

                byte[] imageBytes = file.getBytes();

                BASE64Encoder base64Encoder = new BASE64Encoder();

                String base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(imageBytes);

                base64EncoderImg = base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");
                //System.out.println(base64EncoderImg);
                String attachment = base64EncoderImg;
                JZTAttachmentBusiness jztAttachmentBusiness = new JZTAttachmentBusiness();
                jztAttachmentBusiness.setAttachment(attachment);
                jztAttachmentBusiness.setBusinessOrderNumber(businessOrderNumber);
                jztAttachmentBusiness.setUserName(userName);
                jztAttachmentBusinessList.add(jztAttachmentBusiness);
            }

            MongoDbInfoVO mongoDbInfoVO1 = new MongoDbInfoVO();
            Gson gson1 = new GsonBuilder()
                    .setDateFormat("yyyy-MM-dd HH:mm:ss")
                    .create();
            String jztAttachmentBusinesssStr1 = gson1.toJson(jztAttachmentBusinessList);
            CryptoPrimitives suite1 = new CryptoPrimitives();
            suite1.init();
            String hashValue1 = ImagePathHashValueUtil.getHashValue(jztAttachmentBusinesssStr1, suite1);

            mongoDbInfoVO1.setHashValue(hashValue1);
            mongoDbInfoVO1.setInfoList(jztAttachmentBusinessList);
            mongoDbInfoVO1.setInfoTableName("jzt_attachment_businesss");

            String mongodbInfo = gson1.toJson(mongoDbInfoVO1);


            InputStream inputStream = IOUtils.toInputStream(mongodbInfo, StandardCharsets.UTF_8);

            Map<String, Object> documentMap = new HashMap<>();
            documentMap.put("userName", userName);
            documentMap.put("businessOrderNumber", businessOrderNumber);

            GridFSBucket gridFSFilesBucket = GridFSBuckets.create(mongoDatabase, "jztAttachmentBusinessList");
            GridFSUploadOptions options = new GridFSUploadOptions()
                    .chunkSizeBytes(261120)
                    .metadata(new Document("documentMap", documentMap));
            String fileName = "mongodb-jzt-attachment-businesss-0";
            ObjectId fileId = gridFSFilesBucket.uploadFromStream(fileName, inputStream, options);
            if (EmptyUtils.isNotEmpty(fileId)) {
                msg = "信息上链成功";
                return DtoUtil.returnSuccess(msg);
            } else {
                msg = "信息上链失败";
                return DtoUtil.returnFail(msg, "100001");
            }

        } catch (InvocationTargetException e) {
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


    @RequestMapping(value = "/addJZTAttachmentBusiness", method = RequestMethod.POST)
    @ResponseBody
    public Dto addJZTBatchAttachmentBusiness(HttpServletRequest request) throws Exception {

        String jwtToken = request.getHeader("Authorization");
        String tokenUserName = jwtTokenUtil.getUsernameFromToken(jwtToken);
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        List<MultipartFile> files = multipartRequest.getFiles("files");
        String businessOrderNumber = request.getParameter("businessOrderNumber");
        String userName=request.getParameter("userName");
        if (files.size() < 1) {
            return DtoUtil.returnFail("文件不能为空", "100001");
        }
        if (EmptyUtils.isEmpty(userName)) {
            return DtoUtil.returnFail("用户名不能为空", "100002");
        }
        if (EmptyUtils.isEmpty(businessOrderNumber)) {
            return DtoUtil.returnFail("业务单号不能为空", "100003");
        }
        TrackUser trackUser=trackUserService.getUserByCode(userName);
        if(EmptyUtils.isEmpty(trackUser)){
            String msg="用户找不到";
            return DtoUtil.returnFail(msg,"100006");
        }

        if(!tokenUserName.equals(userName)){
            String msg="用户名跟token用户名不匹配";
            return DtoUtil.returnFail(msg,"100005");
        }
        String msg = "";
        List<Integer> successList = new ArrayList<>();
        List<Integer> failList = new ArrayList<>();
        Map<String, Object> documentMap = new HashMap<>();
        documentMap.put("userName", userName);
        documentMap.put("businessOrderNumber", businessOrderNumber);


        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date createTime = sdf.parse(sdf.format(currentDate));
        Date updateTime = createTime;
        for (int i = 0; i < files.size(); i++) {

            System.out.println("current file index:" + i);
            try {
                documentMap.put("offset", i);
                InputStream inputStream = files.get(i).getInputStream();
                String contentType = files.get(i).getContentType();

                documentMap.put("contentType",contentType);

                String bucketName="jztAttachmentBusinessList";
                GridFSBucket gridFSFilesBucket = GridFSBuckets.create(mongoDatabase,bucketName);
                /*MongoCollection<Document> mongoCollection=mongoDatabase.getCollection("jztAttachmentBusinessList");
                mongoCollection.createIndex(new Document("",""));*/
                GridFSUploadOptions options = new GridFSUploadOptions()
                        .chunkSizeBytes(261120)
                        .metadata(new Document("documentMap", documentMap));
                String fileName = "mongodb-jzt-attachment-businesss-0";

                double dataCount=files.get(i).getSize()/1000000.00;
                String dataType="jztAttachmentBusiness";
                HashChainStatistics hashChainStatistics=new HashChainStatistics();
                hashChainStatistics.setDataCount(dataCount);
                hashChainStatistics.setDataType(dataType);
                hashChainStatistics.setUserName(userName);
                hashChainStatistics.setCreateTime(createTime);
                hashChainStatistics.setUpdateTime(updateTime);
                /*Integer flag=hashChainStatisticsService.add(hashChainStatistics);
                if (flag == 0){
                    throw new Exception("record statistcs error");
                }
                ObjectId fileId = gridFSFilesBucket.uploadFromStream(fileName, inputStream, options);*/
                //ObjectId objectId=hashChainStatisticsService.insertDataCountAndMongoDBGridFS(hashChainStatistics,fileName,inputStream,options,gridFSFilesBucket);
                ObjectId objectId=mysqlDataBaseAndMongDbConfigService.insertDataCountAndMongoDBGridFS(hashChainStatistics,fileName,inputStream,options,gridFSFilesBucket);
                if (EmptyUtils.isEmpty(objectId)) {
                    failList.add(i);
                } else {
                    successList.add(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
                failList.add(i);
            }
        }
        if (failList.size() == 0) {
            msg = "信息上链成功";
            return DtoUtil.returnSuccess(msg);
        } else if (successList.size() == 0) {
            msg = "信息上链失败";
            return DtoUtil.returnFail(msg, "100001");
        } else {
            msg = "success: " + successList.size() + ", fail: " + failList.size()+".\n Success list: " + successList.toString()+".\n Fail list: " + failList.toString();
            return DtoUtil.returnFail(msg, "100002");
        }

    }


    @RequestMapping(value = "/addJZTAttachmentBusinessTest", method = RequestMethod.POST)
    @ResponseBody
    public Dto addJZTAttachmentBusinessTest(HttpServletRequest request) throws Exception {


        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        InputStream multiStream = multipartRequest.getInputStream();

        String msg = "";

        InputStream inputStream1 = IOUtils.toInputStream(multiStream.toString(), StandardCharsets.UTF_8);
        GridFSBucket gridFSFilesBucket = GridFSBuckets.create(mongoDatabase, "jztAttachmentBusinessList");
        GridFSUploadOptions options = new GridFSUploadOptions()
                .chunkSizeBytes(261120).metadata(new Document("documentMap", "documentMap"));
        String fileName = "mongodb-jzt-attachment-businesss";
        ObjectId fileId = gridFSFilesBucket.uploadFromStream(fileName, inputStream1, options);

        if (EmptyUtils.isNotEmpty(fileId)) {
            msg = "信息上链成功";
            return DtoUtil.returnSuccess(msg);
        } else {
            msg = "信息上链失败";
            return DtoUtil.returnFail(msg, "100001");
        }
    }


    @RequestMapping(value = "/getJZTAttachmentBusinessByBusinessOrderNumber", method = RequestMethod.POST)
    @ResponseBody
    public Dto getJZTAttachmentBusinessByBusinessOrderNumber(@RequestParam(value = "businessOrderNumber", required = true) String businessOrderNumber, HttpServletRequest request) throws Exception {
        String jwtToken = request.getHeader("Authorization");
        String userName = jwtTokenUtil.getUsernameFromToken(jwtToken);
        List<JZTAttachmentBusinessVO> jztAttachmentBusinessVOS = jztAttachmentBusinessService.grantGetJZTAttachmentBusinessByBusiness(businessOrderNumber,userName);
        if (jztAttachmentBusinessVOS.size() > 0) {
            return DtoUtil.returnSuccess("查询成功", jztAttachmentBusinessVOS);
        } else {
            return DtoUtil.returnFail("未查询到记录", "10001");
        }
    }


    @RequestMapping(value = "/getAttachmentByBusinessOrderNumber", method = RequestMethod.POST)
    @ResponseBody
    public Dto getAttachmentByBusinessOrderNumber(@RequestParam(value = "businessOrderNumber", required = true) String businessOrderNumber, HttpServletRequest request) throws Exception {
        String jwtToken = request.getHeader("Authorization");
        String userName = jwtTokenUtil.getUsernameFromToken(jwtToken);
        List<JZTAttachmentBusinessVO> jztAttachmentBusinessVOS = jztAttachmentBusinessService.grantGetJZTAttachmentBusinessByBusiness(businessOrderNumber,userName);
        List<ImageAttachementVO> attachementVOList = new ArrayList<>();
        GridFSBucket gridFSFilesBucket = GridFSBuckets.create(mongoDatabase, "jztAttachmentBusinessList");
        for (int i = 0; i < jztAttachmentBusinessVOS.size(); i++) {
            JZTAttachmentBusinessVO jztAttachmentBusinessVO=jztAttachmentBusinessVOS.get(i);
            String contentType=jztAttachmentBusinessVO.getContentType();
            String objectId = jztAttachmentBusinessVO.getObjectId();
            ImageAttachementVO imageAttachementVO = MongoDBGridFSUtil.getJZTAttachmentByObjectId(gridFSFilesBucket, new ObjectId(objectId),contentType);
            attachementVOList.add(imageAttachementVO);
        }
        if (attachementVOList.size() > 0) {
            return DtoUtil.returnSuccess("查询成功", attachementVOList);
        } else {
            return DtoUtil.returnFail("未查询到记录", "10001");
        }
    }


}
